package com.niiwoo.civet.trade.service.local.contract;

import com.alibaba.fastjson.JSONObject;
import com.dangdang.ddframe.rdb.sharding.api.HintManager;
import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder;
import com.niiwoo.civet.trade.constant.RabbitConstant;
import com.niiwoo.civet.trade.dao.entity.KaoLaSignNotifyRecord;
import com.niiwoo.civet.trade.dao.entity.Project;
import com.niiwoo.civet.trade.dao.entity.ProjectContract;
import com.niiwoo.civet.trade.dao.mapper.KaoLaSignNotifyRecordMapperExt;
import com.niiwoo.civet.trade.dao.mapper.ProjectContractMapperExt;
import com.niiwoo.civet.trade.dao.mapper.ProjectMapperExt;
import com.niiwoo.civet.trade.dto.request.kaola.KaoLaDebtResultNotifyRequestDTO;
import com.niiwoo.civet.trade.dto.request.kaola.KaoLaSignNotifyUrlDTO;
import com.niiwoo.civet.trade.dto.response.kaola.KaoLaBaseResponseDTO;
import com.niiwoo.civet.trade.dto.response.kaola.KaoLaCreditAssignmentResponseDTO;
import com.niiwoo.civet.trade.enums.FadadaContractEnum;
import com.niiwoo.civet.trade.enums.kaola.KaoLaLiCaiContractSignStatusEnum;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Objects;
import java.util.UUID;

/**
 * @author liming
 * @date 2017-12-29 17:16
 */
@Slf4j
@Service
public class KaoLaLiCaiContract {

    @Autowired
    private KaoLaSignNotifyRecordMapperExt kaoLaSignNotifyRecordMapperExt;

    @Autowired
    private ProjectMapperExt projectMapperExt;

    @Autowired
    private ProjectContractMapperExt projectContractMapperExt;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;

    /**
     * 考拉待签合同消息通知处理
     *
     * @param kaoLaSignNotifyUrlDTO
     * @return
     */
    public  KaoLaCreditAssignmentResponseDTO kaolaSignNotify(KaoLaSignNotifyUrlDTO kaoLaSignNotifyUrlDTO){
        KaoLaCreditAssignmentResponseDTO responseDTO = new KaoLaCreditAssignmentResponseDTO();
        responseDTO.setResult(KaoLaBaseResponseDTO.KaoLaBaseResponseResultEnum.FAIL.getCode());
        responseDTO.setMessage(KaoLaBaseResponseDTO.KaoLaBaseResponseResultEnum.FAIL.getDescription());

        //1.记录请求记录
        final KaoLaSignNotifyRecord kaoLaSignNotifyRecord = new KaoLaSignNotifyRecord();
        UUID uuid = UUID.randomUUID();
        String transaction_id = uuid.toString();
        JSONObject json = JSONObject.parseObject(kaoLaSignNotifyUrlDTO.getEx_info());
        kaoLaSignNotifyRecord.setId(snowflakeIdWorker.nextId());
        kaoLaSignNotifyRecord.setSendAppId(kaoLaSignNotifyUrlDTO.getSend_app_id());
        kaoLaSignNotifyRecord.setContractId(kaoLaSignNotifyUrlDTO.getContract_id());
        kaoLaSignNotifyRecord.setCustomerId(kaoLaSignNotifyUrlDTO.getCustomer_ids());
        kaoLaSignNotifyRecord.setPushTransactionId(kaoLaSignNotifyUrlDTO.getPush_transaction_id());
        kaoLaSignNotifyRecord.setExInfo(kaoLaSignNotifyUrlDTO.getEx_info());
        kaoLaSignNotifyRecord.setRequestDate(kaoLaSignNotifyUrlDTO.getTimestamp());
        kaoLaSignNotifyRecord.setMsgDigest(kaoLaSignNotifyUrlDTO.getMsg_digest());
        kaoLaSignNotifyRecord.setStatus(KaoLaLiCaiContractSignStatusEnum.INIT.getStatus());
        kaoLaSignNotifyRecord.setCreateTime(new Date());
        kaoLaSignNotifyRecord.setUpdateTime(kaoLaSignNotifyRecord.getCreateTime());
        kaoLaSignNotifyRecord.setTransactionId(transaction_id);
        kaoLaSignNotifyRecord.setProjectId(json.getLong("subjectId"));

        Project project = projectMapperExt.selectByPrimaryKey(kaoLaSignNotifyRecord.getProjectId());
        if(Objects.isNull(project)){
            log.error("[考拉法大大债权转让协议]-考拉待签合同同步你我金融异常,原因是标的不存在,kaoLaSignNotifyUrlDTO: {}", kaoLaSignNotifyUrlDTO);
            return responseDTO;
        }

        //2.新增t_tc_project_contract
        ProjectContract projectContract=new ProjectContract();
        projectContract.setId(snowflakeIdWorker.nextId());
        projectContract.setProjectId(kaoLaSignNotifyRecord.getProjectId());
        projectContract.setUserId(project.getBorrowUserId());
        projectContract.setContractNo(kaoLaSignNotifyRecord.getContractId());
        projectContract.setTransactionId(kaoLaSignNotifyRecord.getTransactionId());
        projectContract.setContractType(FadadaContractEnum.ContractTypeEnum.KAOLA_TRANSFER_CONTRACT.getType());//债权转让协议
        projectContract.setTradeType(FadadaContractEnum.TradeTypeEnum.LOAN.getType());//借款
        projectContract.setOrderId(kaoLaSignNotifyRecord.getProjectId());
        projectContract.setStatus(FadadaContractEnum.StatusEnum.NO.getStatus());//未签署（初始化）
        projectContract.setIsAuto(FadadaContractEnum.IsAutoEnum.AUTO.getType());//自动签署
        projectContract.setCreateTime(new Date());
        projectContract.setUpdateTime(new Date());


        KaoLaLiCaiContract proxy = (KaoLaLiCaiContract)AopContext.currentProxy();
        proxy.initAndSend(kaoLaSignNotifyRecord,projectContract);

        responseDTO.setResult(KaoLaBaseResponseDTO.KaoLaBaseResponseResultEnum.SUCCESS.getCode());
        responseDTO.setMessage(KaoLaBaseResponseDTO.KaoLaBaseResponseResultEnum.SUCCESS.getDescription());
        return responseDTO;
    }


    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public KaoLaSignNotifyRecord initAndSend(KaoLaSignNotifyRecord kaoLaSignNotifyRecord,ProjectContract projectContract) {
        // 相关合同表数据初始化
        kaoLaSignNotifyRecordMapperExt.insertSelective(kaoLaSignNotifyRecord);
        projectContractMapperExt.insertSelective(projectContract);

        log.error("考拉待签合同消息通知,记录请求结束,准备发送考拉法大大债转协议签署消息,kaoLaSignNotifyRecordId={}", kaoLaSignNotifyRecord.getId());
        rabbitTemplate.convertAndSend(RabbitConstant.Exchange.KAOLA_EXCHANGE, RabbitConstant.RoutingKey.KAOLA_CREDIT_ASSIGNMENT_CONTRACT, kaoLaSignNotifyRecord.getId());
        log.error("考拉待签合同消息通知,记录请求结束,发送完成考拉法大大债转协议签署消息,kaolaSignNotifyRecordId={}", kaoLaSignNotifyRecord.getId());
        return kaoLaSignNotifyRecord;
    }



    public KaoLaBaseResponseDTO kaolaDebtResultNotify(KaoLaDebtResultNotifyRequestDTO requestDTO) {
        KaoLaBaseResponseDTO kaoLaBaseResponseDTO = new KaoLaBaseResponseDTO();
        kaoLaBaseResponseDTO.setResult(KaoLaBaseResponseDTO.KaoLaBaseResponseResultEnum.FAIL.getCode());
        kaoLaBaseResponseDTO.setMessage(KaoLaBaseResponseDTO.KaoLaBaseResponseResultEnum.FAIL.getDescription());
        if (!HintManagerHolder.isMasterRouteOnly()) {
            HintManagerHolder.clear();
            HintManager hintManager = HintManager.getInstance();
            hintManager.setMasterRouteOnly();
        }
        //1.更新t_tc_kaola_sign_notify_record
        KaoLaSignNotifyRecord kaolaSignNotifyRecord = kaoLaSignNotifyRecordMapperExt.selectByTransactionId(requestDTO.getTransaction_id());
        if(Objects.isNull(kaolaSignNotifyRecord)) {
            log.error("考拉法大大债权转让协议签署结果异步通知,发生异常,原因是根据交易号查询不到KaoLaSignNotifyRecord,交易号={}", requestDTO.getTransaction_id());
            return kaoLaBaseResponseDTO;
        }

        Project project = projectMapperExt.selectByPrimaryKey(kaolaSignNotifyRecord.getProjectId());
        if(Objects.isNull(project)){
            log.error("考拉法大大债权转让协议签署结果异步通知,发生异常,原因是标的不存在,交易号={},标的ID={}", requestDTO.getTransaction_id(),kaolaSignNotifyRecord.getProjectId());
            return kaoLaBaseResponseDTO;
        }

        KaoLaSignNotifyRecord kaolaSignNotifyRecord4Update = new KaoLaSignNotifyRecord();
        kaolaSignNotifyRecord4Update.setId(kaolaSignNotifyRecord.getId());
        kaolaSignNotifyRecord4Update.setStatus(requestDTO.isSuccess() ? KaoLaLiCaiContractSignStatusEnum.SUCCESS.getStatus() : KaoLaLiCaiContractSignStatusEnum.FAILED.getStatus());
        kaolaSignNotifyRecord4Update.setUpdateTime(new Date());
        //不适用transaction_id查询(无索引)
        ProjectContract projectContract = projectContractMapperExt.queryProjectContract4KaoLaDebt(project.getBorrowUserId(),requestDTO.getContract_id(),
                project.getProjectId(), FadadaContractEnum.ContractTypeEnum.KAOLA_TRANSFER_CONTRACT.getType());
        if(Objects.isNull(projectContract)){
            log.error("考拉法大大债权转让协议签署结果异步通知,发生异常,原因是合同记录表t_tc_project_contract未初始化,KaoLaDebtResultNotifyRequestDTO: {}", requestDTO);
            return kaoLaBaseResponseDTO;
        }
        if(FadadaContractEnum.StatusEnum.YES.getStatus().equals(projectContract.getStatus())){
            kaoLaBaseResponseDTO.setResult(KaoLaBaseResponseDTO.KaoLaBaseResponseResultEnum.SUCCESS.getCode());
            kaoLaBaseResponseDTO.setMessage(KaoLaBaseResponseDTO.KaoLaBaseResponseResultEnum.SUCCESS.getDescription());
            return kaoLaBaseResponseDTO;
        }

        //2.更新t_tc_project_contract
        ProjectContract projectContract4Update=new ProjectContract();
        projectContract4Update.setId(projectContract.getId());
        projectContract4Update.setStatus(requestDTO.isSuccess() ? FadadaContractEnum.StatusEnum.YES.getStatus() :FadadaContractEnum.StatusEnum.NO.getStatus());
        projectContract4Update.setDownloadUrl(requestDTO.getDownload_url());
        projectContract4Update.setViewUrl(requestDTO.getViewpdf_url());
        projectContract4Update.setUpdateTime(new Date());

        KaoLaLiCaiContract proxy = (KaoLaLiCaiContract) AopContext.currentProxy();
        proxy.updateContract(kaolaSignNotifyRecord4Update,projectContract4Update);

        kaoLaBaseResponseDTO.setResult(KaoLaBaseResponseDTO.KaoLaBaseResponseResultEnum.SUCCESS.getCode());
        kaoLaBaseResponseDTO.setMessage(KaoLaBaseResponseDTO.KaoLaBaseResponseResultEnum.SUCCESS.getDescription());
        return kaoLaBaseResponseDTO;
    }

    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void updateContract(KaoLaSignNotifyRecord kaolaSignNotifyRecord4Update,ProjectContract projectContract4Update){
        kaoLaSignNotifyRecordMapperExt.updateByPrimaryKeySelective(kaolaSignNotifyRecord4Update);
        projectContractMapperExt.updateByPrimaryKeySelective(projectContract4Update);
    }
}
